package repositorioJuego;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import compartido.IEntidad;
import compartido.Usuario;
import compartido.filtros.IFiltro;
import compartido.filtros.Tautologia;

import persistencia.compartido.Repositorio;
import persistencia.compartido.Tipo;
import modelo.carrera.Carrera;
import modelo.carrera.Jugador;
import modelo.carrera.filtros.EsCarreraFinalizada;
import modelo.carrera.filtros.EsCarreraSiendoSimulada;

public class RepositorioJuego implements IRepositorioJuego {
	// 30 minutos en milisegundos;
	protected static long tolerancia = 30L*60L*1000L;
	protected Repositorio repositorio;
	
	protected static RepositorioJuego instancia = null;
	protected static String directorio = null;
	
	public static String getDirectorio() {
		if (directorio == null)
			directorio = ".";
		return directorio;
	}
	
	public static void setDirectorio(String directorioDeTrabajo) {
		if (directorio == null)
			directorio = directorioDeTrabajo;
	}
	
	protected RepositorioJuego() {
		File directorio = new File(getDirectorio());
		if (!directorio.exists())
			directorio.mkdirs();
		
		repositorio = new Repositorio(directorio.getAbsolutePath());
	}

	public static RepositorioJuego getInstancia() {
		if (instancia == null) {
			instancia = new RepositorioJuego();			
			if (!instancia.UsuariosDefinidos()) {
				instancia.addUsuario(new Usuario("admin","admin"));
			}
		}
		return instancia;
	}
	
	protected boolean UsuariosDefinidos() {
		Tipo<IEntidad> tipoUsuarios = new Tipo<IEntidad>(Usuario.class);
		Iterator<IEntidad> usuarios = repositorio.iterarEntidades(tipoUsuarios);
		
		return  ( (usuarios != null) && (usuarios.hasNext()) );
	}
		
	public List<Carrera> FiltrarCarrera(IFiltro<Carrera> filtro) {
		ArrayList<Carrera> carreras = new ArrayList<Carrera>();
		
		Tipo<IEntidad> tipoCarreras = new Tipo<IEntidad>(Carrera.class);
		Iterator<IEntidad> entidades = repositorio.iterarEntidades(tipoCarreras);
		
		if (entidades != null) { 
			while (entidades.hasNext()) {
				IEntidad entidad = entidades.next();
				if (entidad instanceof Carrera) {
					Carrera carrera = (Carrera)entidad;
					
					if (filtro.cumple(carrera))
						carreras.add(carrera);
				}
				
			}
		}
		return carreras;
	}
	

	public List<Carrera> CarreraParaMostrar() {
		return FiltrarCarrera(new EsCarreraSiendoSimulada(tolerancia));
	}


	public void addJugador(Jugador jugador, String idCarrera) {
		
		Carrera carrera = getCarrera(idCarrera);
		carrera.agregarJugador(jugador);
		repositorio.guardarEntidad(carrera);
		repositorio.guardar();
	}


	public List<Carrera> buscarTodaLasCarreras() {
		return FiltrarCarrera(new Tautologia<Carrera>());
	}

	
	public Carrera getCarrera(String idCarrera) {		
		Tipo<IEntidad> tipoCarreras = new Tipo<IEntidad>(Carrera.class);
		IEntidad entidad = repositorio.obtenerEntidad(tipoCarreras, idCarrera);

		Carrera buscada = null;
		if (entidad instanceof Carrera)
			buscada = (Carrera)entidad;
		return buscada;
	}

	
	public List<Jugador> obtenerListaGanadores(String idCarrera) {
		
		List<Jugador> ganadores = null;
		Carrera carrera = getCarrera(idCarrera);
		if (carrera != null)
			ganadores = carrera.getJugadores();
		
		return ganadores;
	}


	public List<Carrera> recuperarCarreraFinalizada() {
		return FiltrarCarrera(new EsCarreraFinalizada());
	}	

	@Override
	public void addUsuario(Usuario usuarioNuevo) {
		Usuario existente = getUsuario(usuarioNuevo.getIdentificador());
		if (existente == null) {
			repositorio.guardarEntidad(usuarioNuevo);
			repositorio.guardar();
		}
	}

	@Override
	public Usuario getUsuario(String nombre) {
		Usuario usuario = null;
		Tipo<IEntidad> tipo = new Tipo<IEntidad>(Usuario.class);
		IEntidad entidad = repositorio.obtenerEntidad(tipo, nombre);
		if (entidad instanceof Usuario)
			usuario = (Usuario)entidad;
		
		return usuario;
	}

	@Override
	public void removeUsuario(Usuario usuarioAEliminar) {
		Usuario existente = getUsuario(usuarioAEliminar.getIdentificador());
		
		if (existente != null) {
			boolean passwordCorrecto = (existente.compareTo(usuarioAEliminar) == 0);
			if (passwordCorrecto)
				repositorio.eliminarEntidad(existente);
		}
	}
	
	public void guardar() {
		repositorio.guardar();
	}	
}
